import { IParallel } from "../../interface/composite/IParallel";
import { BaseComposite } from "../../base/BaseComposite";
import { myclass } from "../../../../engine/decorators";
import { EPolicy, EStatus } from "../../common/EnumType";
@myclass("ParallelImpl")
export class ParallelImpl extends BaseComposite implements IParallel {
    successPolocy: EPolicy;
    failPolocy: EPolicy;

    public setConfig(config: any, unitUID: number): void{
        super.setConfig(config, unitUID);
        this.successPolocy = this.config.params.successPolocy;
        this.failPolocy = this.config.params.failPolocy;
    }

    public onUpdate(): EStatus {
        let successCount = 0;
        let failureCount = 0;
        let iBehaviours = this.getChildren();
        let childrenSize = iBehaviours.length;

        for (let i = 0; i < iBehaviours.length; i++) {
            //如果行为已经终止则不再执行该行为
            if (!(iBehaviours[i].getStatus() == EStatus.Success || iBehaviours[i].getStatus() == EStatus.Failure))
                iBehaviours[i].tick();

            if (iBehaviours[i].getStatus() == EStatus.Success) {
                successCount++;
                if (this.successPolocy == (EPolicy.RequireOne)) {
                    iBehaviours[i].reset();
                    return EStatus.Success;
                }
            }

            if (iBehaviours[i].getStatus() == EStatus.Failure) {
                failureCount++;
                if (this.failPolocy == EPolicy.RequireOne) {
                    iBehaviours[i].reset();
                    return EStatus.Failure;
                }
            }

        }

        if (this.failPolocy == EPolicy.RequireAll && failureCount == childrenSize) {
            iBehaviours.forEach(iBehaviour => {
                iBehaviour.reset();
            });
            return EStatus.Failure;
        }
        if (this.successPolocy == EPolicy.RequireAll && successCount == childrenSize) {
            iBehaviours.forEach(iBehaviour => {
                iBehaviour.reset();
            });
            return EStatus.Success;
        }

        return EStatus.Running;
    }

    public onTerminate(status: EStatus): void {
        this.getChildren().forEach(iBehaviour => {
            if (iBehaviour.getStatus() == EStatus.Running) {
                iBehaviour.abort();
            }

            iBehaviour.reset();
        });
    }
}